#include "server.h"

int main(){
	int sockfd,ret,cfd,port;
    char ip[64];
    pid_t pid;
	sqlite3 *pdb = NULL; // 数据库
	pdb = create_db_engine("./data.db"); // 创建数据库
	struct sockaddr_in cliaddr;
	socklen_t addrlen = sizeof(struct sockaddr_in);
	signal(SIGCHLD,handle);

	sockfd = sock_init();// 创建监听套接字
	if(sockfd < 0){
		return -1;
	}
    
	while(1){
        // 等待客户端链接
        cfd = accept(sockfd,(struct sockaddr*)&cliaddr,&addrlen);
        if(cfd < 0){
            perror("accept");
            return -1;
        }
        port = ntohs(cliaddr.sin_port);
        inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,ip,64);
        printf("------------------------------\n");
        printf("client[%s:%d]connect\n",ip,port);
        printf("------------------------------\n");

        pid = fork();
        if(pid == 0)    break;

        close(cfd);
        cfd = -1;
    }

	close(sockfd);
	sockfd = -1;
	struct pack* pk;
	while(1){
		// 读取客户端请求
		pk = (struct pack*)malloc(sizeof(struct pack));
        ret = read(cfd, pk, sizeof(struct pack));
        if(ret <= 0){
			deal_return_value("read", ret, cfd);
			break;
		}
        // 根据包头中的类型确定是什么请求
        switch(pk->type){
        case REG_REQ:
            deal_reg_req(cfd,pdb);
			break;
        case LOGIN_REQ:
            deal_login_req(cfd,pdb);
            break;
        }
    }
    close(cfd);
    cfd = -1;

    return 0;
}
//ok
void deal_return_value(char *name, int ret, int cfd){
	if(ret < 0)	perror(name);
	else if(ret == 0)printf("TCP  broken...\n");

	close(cfd);
    cfd = -1;
}
//ok
void handle(int sig){
    wait(NULL); // 回收进程
    printf("------------------------------\n");
}

/*处理注册请求ok*/
int deal_reg_req(int cfd,sqlite3 *pdb){
	int ret;
	struct user_info *usr;

	/*读取注册的信息*/
	ret = read(cfd, &usr, sizeof(struct user_info));
	if(ret <= 0){
		deal_return_value("read", ret, cfd);
		return -1;
	}

	struct pack pk;
	pk.ver = 0;
	pk.len = 0;
	pk.type = REG_FAIL;
	
	/*处理注册请求*/
	ret = register_new_user(pdb,usr);
	if(ret == 0){// 成功
		pk.type = REG_OK;
		printf("注册了一个新用户...\n");
	}
	else if(ret == 1){ // 失败
		printf("用户%s已存在,无法注册\n",usr->name);
	}
	else{ // 失败
		pk.type = SERVER_FAIL;
		printf("ERROR!系统故障,注册失败...\n");
	}

	/*将结果回复给客户端*/
	ret = write(cfd, &pk, sizeof(struct pack));
	if(ret <= 0){
		deal_return_value("write", ret, cfd);
		return -1;
	}

	return 0;
}

/*处理登录请求ok*/
int deal_login_req(int cfd,sqlite3 *pdb){
	int ret;
	struct user_info *usr;

	// 读取登录的信息
	ret = read(cfd, &usr, sizeof(struct user_info));
	if(ret <= 0){
		deal_return_value("read", ret, cfd);
		return -1;
	}

	struct pack pk;
	pk.ver = 0;
	pk.len = 0;
	pk.type = LOGIN_OK;

	/*处理注册请求*/
	ret = user_login(pdb,usr);
	if(ret == 0){
		printf("登陆成功...\n");
	}
	else if(ret == 1){
		pk.type = LOGIN_FAIL1;
		printf("该用户不存在...\n");
	}
	else if(ret == 2){
		pk.type = LOGIN_FAIL2;
		printf("密码错误...\n");
	}
	else if(ret == 3){
		pk.type = LOGIN_FAIL3;
		printf("该用户已登录...\n");
	}
	else{
		pk.type = SERVER_FAIL;
		printf("ERROR!系统错误,登录失败...\n");
	}

	// 4、将结果回复给客户端
	ret = write(cfd, &pk, sizeof(struct pack));
	if(ret <= 0){
		deal_return_value("write", ret, cfd);
		return -1;
	}

	return 0;
}

/*创建套接字ok*/
int sock_init(){
    int sockfd,ret;
	int opt = 1;
	struct sockaddr_in seraddr;
    // 创建监听套接字 socket()
    sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd < 0){
        perror("socket");
        return -1;
    }

    // 设置接口复用选项 setsockopt()
    ret = setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
    if(ret < 0){
        perror("setsockopt");
        return -1;
    }
    
    seraddr.sin_family = AF_INET;
    seraddr.sin_port = htons(9999);
    inet_pton(AF_INET,"127.0.0.1",&seraddr.sin_addr.s_addr);
    // 绑定ip和端口号
    ret = bind(sockfd,(struct sockaddr*)&seraddr,sizeof(struct sockaddr_in));
    if(ret < 0){
        perror("bind");
        return -1;
    }
    ret = listen(sockfd,10);
    if(ret < 0){
        perror("listen");
        return -1;
    }
    return sockfd;
}

/*处理查词请求*/
int deal_query_req(int cfd,struct pack* pk){
	int ret;
	char *word;
	word = (char*)malloc(pk->len); // malloc
	// 读取信息
	ret = read(cfd, word, sizeof(struct user_info));
	if(ret <= 0){
		deal_return_value("read", ret, cfd);
		return -1;
	}

	
	struct pack return_pk;
	pk->ver = 0;
	pk->len = 0;
	pk->type = QUERY_OK;
	


	// 4、将结果回复给客户端
	ret = write(cfd, &return_pk, sizeof(struct pack));
	if(ret <= 0){
		deal_return_value("write", ret, cfd);
		return -1;
	}

	return 0;
}

/*处理历史记录请求*/
int deal_history_req(int cfd){
	return 0;
}
/*查词*/
char* query_dictionary(char* word){
	// FILE *fp = NULL;
	// int i = 0;

	// // 打开文件
	// fp = fopen(DICTIONARY_PATH, "r");
	// if(fp == NULL){
	// 	printf("open dictionary failed...\n");
	// 	return -1;
	// }

	// // 读数据
	// while(1){
	// 	if(EOF == fscanf(fp, "%s %s", t[i].name, t[i].passwd))  break;
	// 	i ++;
	// }

    // // 关闭文件
	// fclose(fp);
    // fp = NULL;
	// return i;
	return NULL;
}
